import UIKit

// 尾闭包

func trailingClosure(work: (String) -> Void, test: (String) -> Void) {
  work("test")
}

// 如果使用尾闭包,且函数不止使用一个闭包作为参数
// 那么第一个闭包不写参数标签
trailingClosure { _ in

} test: { _ in
}

func dowork(name: () -> Void, sex: String, age: () -> Void) {
}

dowork(name: {
}, sex: "1") {
}

func makeHouse(name: () -> Void, age: () -> Void, project: () -> Void) {
}

makeHouse {
} age: {
} project: {
}

// 闭包的引用self

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
  completionHandlers.append(completionHandler)
}


//自动闭包
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count)
// Prints "5"


let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count)
// Prints "5"


print("Now serving \(customerProvider())!")
// Prints "Now serving Chris!"
print(customersInLine.count)
// Prints "4"


// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: () -> String) {
  print("Now serving \(customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) } )
// Prints "Now serving Alex!"

print(customersInLine)
// customersInLine is ["Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: @autoclosure () -> String) {
  print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))
// Prints "Now serving Ewa!"


//自动闭包+逃逸闭包
// customersInLine is ["Barry", "Daniella"]
var customerProviders: [() -> String] = []
func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
  customerProviders.append(customerProvider)  //customerProvider未调用,只添加到数组中
}
//闭包未调用
collectCustomerProviders(customersInLine.remove(at: 0))
collectCustomerProviders(customersInLine.remove(at: 0))


print("Collected \(customerProviders.count) closures.")
// Prints "Collected 2 closures."
for customerProvider in customerProviders {
  print("Now serving \(customerProvider())!")
}
// Prints "Now serving Barry!"
// Prints "Now serving Daniella!"



func expensiveOperation() -> Bool {
  print("Executing expensive operation...")
  return true
}

func performOperation(onlyIf condition: @autoclosure () -> Bool) {
  if condition() {
    print("Operation performed")
  } else {
    print("Operation skipped")
  }
}

performOperation(onlyIf: expensiveOperation())
